//
// Created by pzw on 24-2-26.
//

#include "ArrayList.h"

template<typename E>
ArrayList<E>::ArrayList() {
    vector = {};
}

template<typename E>
ArrayList<E>::~ArrayList() {
    vector.clear();
    /* 不需要调用delete &vector;会自动回收的 */
}

template<typename E>
bool ArrayList<E>::add(E element) {
    vector.push_back(element);
    return false;
}

template<typename E>
bool ArrayList<E>::add(int index, E element) {
    vector.push_back(vector.begin() + index, element);
    return false;
}

template<typename E>
bool ArrayList<E>::addAll(const std::vector<E> &source) {
    vector.insert(vector.begin(), source.begin(), source.end());
    return false;
}

template<typename E>
bool ArrayList<E>::addAll(int index, const std::vector<E> &collection) {
    if (index < 0 || index > vector.size()) {
        std::cerr << "Index out of bounds" << std::endl;
        return false;
    }

    vector.insert(vector.begin() + index, collection.begin(), collection.end());
}

template<typename E>
void ArrayList<E>::clear() {
    vector.clear();
}

template<typename E>
ArrayList<E> ArrayList<E>::clone() {
    return ArrayList<E>();
}

template<typename E>
bool ArrayList<E>::contains(E o) {
    for (const E &item: vector) {
        if (item == o) {
            return true;
        }
    }
    return false;
}

template<typename E>
void ArrayList<E>::ensureCapacity(size_t minCapacity) {
    if (vector.capacity() < minCapacity) {
        vector.reserve(minCapacity);
        std::cout << "Capacity increased to at least " << minCapacity << std::endl;
    } else {
        std::cout << "Capacity is already sufficient" << std::endl;
    }
}

template<typename E>
bool ArrayList<E>::equals(const std::vector<E> &vec) {
    if (vector.size() != vec.size()) {
        return false;
    }

    for (size_t i = 0; i < vector.size(); ++i) {
        if (vector[i] != vec[i]) {
            return false;
        }
    }

    return true;
}

template<typename E>
E ArrayList<E>::get(int index) {
    return vector[index];
}

template<typename E>
int ArrayList<E>::hashCode() {
    std::hash<E> hash;
    int hashCode = 0;

    for (const E &element: vector) {
        /*
         * 在计算哈希码时，乘以一个质数（通常选择31）的目的是为了降低哈希冲突的可能性，
         * 即使在处理较小的数据集时也能产生比较均匀的分布。选择31的原因是它是一个奇数，同时又是一个素数，
         * 这有助于减少哈希冲突的可能性。通过乘以31，可以将当前的哈希值左移5位，然后再加上新元素的哈希值，
         * 相当于乘以31并加上新元素的哈希值，这样能够更好地混合各个元素的哈希码，减少冲突的可能性。虽然选择31
         * 是一个常见的做法，但在实际应用中，根据具体情况可能会选择其他质数来进行哈希码的计算。
         */
        hashCode = hashCode * 31 + hash(element);
    }

    return hashCode;
}

template<typename E>
int ArrayList<E>::indexOf(const E &element) {
    for (size_t i = 0; i < vector.size(); i++) {
        if (vector[i] == element) {
            return i;
        }
    }
    return -1; // Element not found
}

template<typename E>
bool ArrayList<E>::isEmpty() {
    return vector.empty() || vector.begin() == vector.end();
}

template<typename E>
Iterator<E> ArrayList<E>::iterator() {
    return Iterator<E>(vector);
}

template<typename E>
int ArrayList<E>::lastIndexOf(E element) {
    for (int i = vector.size() - 1; i >= 0; i--) {
        if (vector[i] == element) {
            return i;
        }
    }
    return -1; // Element not found
}

template<typename E>
ListIterator<E> ArrayList<E>::listIterator() {
    return ListIterator<E>(vector);
}

template<typename E>
ListIterator<E> ArrayList<E>::listIterator(int index) {
    return ListIterator<E>(vector, index);
}

template<typename E>
E ArrayList<E>::remove(int index) {
    if (index < 0 || index >= vector.size()) {
        throw std::out_of_range("Index out of range");
    }

    E removedElement = vector[index];
    vector.erase(vector.begin() + index);
    return removedElement;
}

template<typename E>
bool ArrayList<E>::remove(E &element) {
    const std::istreambuf_iterator<E> &it = std::find(vector.begin(), vector.end(), element);
    if (it != vector.end()) {
        vector.erase(it);
        return true;
    }
    return false;
}

template<typename E>
void ArrayList<E>::removeIf(std::vector<E> &vec, bool (*predicate)(const E &)) {
    vec.erase(std::remove_if(vec.begin(), vec.end(), predicate), vec.end());
}

template<typename E>
bool ArrayList<E>::retainAll(const std::vector<E> &toRetain) {
    std::vector<E> result;
    for (const E &element: vector) {
        if (std::find(toRetain.begin(), toRetain.end(), element) != toRetain.end()) {
            result.push_back(element);
        }
    }

    if (result.size() < vector.size()) {
        vector = result;
        return true;
    }
    return false;
}

template<typename E>
bool ArrayList<E>::removeAll(const std::vector<E> &toRemove) {
    bool removed = false;
    for (const E &element: toRemove) {
        auto it = std::remove(vector.begin(), vector.end(), element);
        if (it != vector.end()) {
            vector.erase(it, vector.end());
            removed = true;
        }
    }
    return removed;
}

template<typename E>
E ArrayList<E>::set(int index, E element) {
    if (index < 0 || index >= vector.size()) {
        throw std::out_of_range("Index out of range");
    }

    E oldElement = vector[index];
    vector[index] = element;
    /* 替换新值成功后，返回旧的值 */
    return oldElement;
}

template<typename E>
int ArrayList<E>::size() {
    return vector.size();
}

template<class E>
void ArrayList<E>::sortWithComparator(bool (*comparator)(const E &, const E &)) {
    std::sort(vector.begin(), vector.end(), comparator);
}

template<class E>
std::vector<E> ArrayList<E>::subList(int fromIndex, int toIndex) {
    if (fromIndex < 0 || toIndex > vector.size() || fromIndex >= toIndex) {
        std::cerr << "Invalid indices for subList" << std::endl;
        return std::vector<E>();
    }

    return std::vector<E>(vector.begin() + fromIndex, vector.begin() + toIndex);
}

template<class E>
E *ArrayList<E>::toArray() {
    E *array = new E[vector.size()];
    for (size_t i = 0; i < vector.size(); ++i) {
        array[i] = vector[i];
    }
    return array;
}

template<class E>
std::string ArrayList<E>::toString() {
    std::stringstream ss;
    ss << "[";
    for (size_t i = 0; i < vector.size(); ++i) {
        if (i > 0) {
            ss << ", ";
        }
        ss << vector[i];
    }
    ss << "]";
    return ss.str();
}

template<typename E>
void ArrayList<E>::trimToSize() {
    std::vector<E>(vector).swap(vector);
}

int vector_api_main() {
    /* 初始化 */
    ArrayList<int> *pList = new ArrayList<int>();
    pList->add(0);
    pList->add(1);
    pList->add(2);
    pList->add(3);
    pList->add(4);
    pList->add(5);
    pList->add(6);
    pList->add(7);
    if (pList->isEmpty()) {
        return -1;
    }

    /* 使用迭代器 */
    ListIterator<int> it = pList->listIterator();
    while (it.hasNext()) {
        int e = it.next();
        if (e == 3) {
            it.remove();
            break;
        }
    }
    std::cout << "vector_api_main: pList = " << pList->toString() << std::endl;
    /* C++原生迭代器使用 */
    const Iterator<int> &itr = pList->iterator();
    itr.vec_itr_main();

    /* 擦除 */
    pList->remove(3);
    pList->clear();

    /* 遍历集合 */
    for (int i = 0; i < pList->size(); i++) {
        std::cout << "vector_api_main: e[" << i << "]" << pList->get(i) << std::endl;
        std::cout << pList->hashCode() << std::endl;
        if (pList->contains(3)) {
            break;
        }
    }
    int *array = pList->toArray();
    for (int i = 0; i < sizeof(array); i++) {
        std::cout << "vector_api_main: " << *(array + i) << ", " << std::endl;
    }
    int size = sizeof(array) / sizeof(array[0]); // 计算数组长度
    int *x = array; // 将指针指向数组的第一个元素
    for (int *ptr = x; ptr < x + size; ++ptr) {
        std::cout << "vector_api_main: " << *ptr << ", " << std::endl;
    }
    std::cout << "vector_api_main: index of 3 = " << pList->indexOf(3) << std::endl;

    delete pList;
    return 0;
}